package impl

import (
	"context"
	"fmt"
	"strings"
	"time"

	"gitee.com/go-course/go8/projects/devcloud/cmdb/apps/host"
	"gitee.com/go-course/go8/projects/devcloud/cmdb/apps/resource"
	"gitee.com/go-course/go8/projects/devcloud/cmdb/apps/secret"
	"gitee.com/go-course/go8/projects/devcloud/cmdb/provider/txyun/connectivity"
	"gitee.com/go-course/go8/projects/devcloud/cmdb/provider/txyun/cvm"
)

func (s *service) CreateSecret(ctx context.Context, req *secret.CreateSecretRequest) (*secret.Secret, error) {
	ins := New(req)
	err := s.db.WithContext(ctx).Create(ins).Error
	if err != nil {
		return nil, err
	}
	return ins.Secret(), nil
}
func (s *service) QuerySecret(ctx context.Context, req *secret.QuerySecretRequest) (*secret.SecretSet, error) {
	set := NewSecretSet()
	err := s.db.WithContext(ctx).Find(&set.Items).Error
	if err != nil {
		return nil, err
	}
	return set.SecretSet(), nil
}

func (s *service) SyncResource(ctx context.Context, req *secret.SyncResourceRequest) (
	*secret.SyncResourceResponse, error) {
	// 1. 查询出凭证
	set, err := s.QuerySecret(ctx, &secret.QuerySecretRequest{})
	if err != nil {
		return nil, err
	}

	for i := range req.Secrets {
		sc := set.Get(req.Secrets[i])
		fmt.Println(sc)
		// 2. 基于凭证构造Operator
		switch sc.Spec.Vendor {
		case resource.VENDOR_TENCENT:
			// 3. 执行Operator操作
			for _, region := range strings.Split(sc.Spec.AllowRegions, ",") {
				// 3.1创建客户端
				client := &connectivity.TencentCloudClient{
					Region:    region,
					SecretID:  sc.Spec.ApiKey,
					SecretKey: sc.Spec.ApiSecret,
				}

				// 3.2 创建cvm operator
				ac, err := client.Account()
				if err != nil {
					panic(err)
				}

				// 3.3 执行查询
				op := cvm.NewCVMOperator(client.CvmClient(), ac)
				pager := op.PageCvmQuery()
				for pager.Next() {
					set := host.NewHostSet()
					if err := pager.Scan(ctx, set); err != nil {
						return nil, err
					}
					// 3.4 保持
					for i := range set.Items {
						item := set.Items[i]
						item.Resource.Meta.Domain = sc.Spec.Domain
						item.Resource.Meta.Namespace = sc.Spec.Namespace
						item.Resource.Meta.SyncAt = time.Now().Unix()

						ins, err := s.host.CreateHost(ctx, item)
						if err != nil {
							s.log.Warnf("save host error, %s", err)
						} else {
							s.log.Debugf("save host %s success", ins.Resource.Spec.Name)
						}
					}
				}
			}

		default:
			return nil, fmt.Errorf("unsport %s", sc.Spec.Vendor.String())
		}
	}

	return &secret.SyncResourceResponse{}, nil
}
